home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / phpMyAdmin / libraries / relation.lib.php < prev    next >
PHP Script  |  2005-03-31  |  34KB  |  853 lines

  1. <?php
  2. /* $Id: relation.lib.php,v 2.34 2005/03/31 21:51:48 lem9 Exp $ */
  3. // vim: expandtab sw=4 ts=4 sts=4:
  4.  
  5. /**
  6.  * Set of functions used with the relation and pdf feature
  7.  */
  8.  
  9. /**
  10.  * Executes a query as controluser if possible, otherwise as normal user
  11.  *
  12.  * @param   string    the query to execute
  13.  * @param   boolean   whether to display SQL error messages or not
  14.  *
  15.  * @return  integer   the result id
  16.  *
  17.  * @global  string    the URL of the page to show in case of error
  18.  * @global  string    the name of db to come back to
  19.  * @global  resource  the resource id of DB connect as controluser
  20.  * @global  array     configuration infos about the relations stuff
  21.  *
  22.  * @access  public
  23.  *
  24.  * @author  Mike Beck <mikebeck@users.sourceforge.net>
  25.  */
  26.  function PMA_query_as_cu($sql, $show_error = TRUE, $options = 0) {
  27.     global $err_url_0, $db, $dbh, $cfgRelation;
  28.  
  29.     PMA_DBI_select_db($cfgRelation['db'], $dbh);
  30.     if ($show_error) {
  31.         $result = PMA_DBI_query($sql, $dbh, $options);
  32.     } else {
  33.         $result = @PMA_DBI_try_query($sql, $dbh, $options);
  34.     } // end if... else...
  35.     PMA_DBI_select_db($db, $dbh);
  36.  
  37.     if ($result) {
  38.         return $result;
  39.     } else {
  40.         return FALSE;
  41.     }
  42.  } // end of the "PMA_query_as_cu()" function 
  43.  
  44.  
  45. /**
  46.  * Defines the relation parameters for the current user
  47.  * just a copy of the functions used for relations ;-)
  48.  * but added some stuff to check what will work
  49.  *
  50.  * @param   boolean  whether to check validity of settings or not
  51.  *
  52.  * @return  array    the relation parameters for the current user
  53.  *
  54.  * @global  array    the list of settings for servers
  55.  * @global  integer  the id of the current server
  56.  * @global  string   the URL of the page to show in case of error
  57.  * @global  string   the name of the current db
  58.  * @global  string   the name of the current table
  59.  * @global  array    configuration infos about the relations stuff
  60.  *
  61.  * @access  public
  62.  *
  63.  * @author  Mike Beck <mikebeck@users.sourceforge.net>
  64.  */
  65. function PMA_getRelationsParam($verbose = FALSE)
  66. {
  67.     global $cfg, $server, $err_url_0, $db, $table;
  68.     global $cfgRelation;
  69.  
  70.     $cfgRelation                = array();
  71.     $cfgRelation['relwork']     = FALSE;
  72.     $cfgRelation['displaywork'] = FALSE;
  73.     $cfgRelation['bookmarkwork']= FALSE;
  74.     $cfgRelation['pdfwork']     = FALSE;
  75.     $cfgRelation['commwork']    = FALSE;
  76.     $cfgRelation['mimework']    = FALSE;
  77.     $cfgRelation['historywork'] = FALSE;
  78.     $cfgRelation['allworks']    = FALSE;
  79.  
  80.     // No server selected -> no bookmark table
  81.     // we return the array with the FALSEs in it,
  82.     // to avoid some 'Unitialized string offset' errors later
  83.     if ($server == 0
  84.        || empty($cfg['Server'])
  85.        || empty($cfg['Server']['pmadb'])) {
  86.         if ($verbose == TRUE) {
  87.             echo 'PMA Database ... '
  88.                  . '<font color="red"><b>' . $GLOBALS['strNotOK'] . '</b></font>'
  89.                  . '[ <a href="Documentation.html#pmadb">' . $GLOBALS['strDocu'] . '</a> ]<br />' . "\n"
  90.                  . $GLOBALS['strGeneralRelationFeat']
  91.                  . ' <font color="green">' . $GLOBALS['strDisabled'] . '</font>' . "\n";
  92.         }
  93.         return $cfgRelation;
  94.     }
  95.  
  96.     $cfgRelation['user']  = $cfg['Server']['user'];
  97.     $cfgRelation['db']    = $cfg['Server']['pmadb'];
  98.  
  99.     //  Now I just check if all tables that i need are present so I can for
  100.     //  example enable relations but not pdf...
  101.     //  I was thinking of checking if they have all required columns but I
  102.     //  fear it might be too slow
  103.     // PMA_DBI_select_db($cfgRelation['db']);
  104.  
  105.     $tab_query = 'SHOW TABLES FROM ' . PMA_backquote($cfgRelation['db']);
  106.     $tab_rs    = PMA_query_as_cu($tab_query, FALSE, PMA_DBI_QUERY_STORE);
  107.  
  108.     if ($tab_rs) {
  109.         while ($curr_table = @PMA_DBI_fetch_row($tab_rs)) {
  110.             if ($curr_table[0] == $cfg['Server']['bookmarktable']) {
  111.                 $cfgRelation['bookmark']        = $curr_table[0];
  112.             } else if ($curr_table[0] == $cfg['Server']['relation']) {
  113.                 $cfgRelation['relation']        = $curr_table[0];
  114.             } else if ($curr_table[0] == $cfg['Server']['table_info']) {
  115.                 $cfgRelation['table_info']      = $curr_table[0];
  116.             } else if ($curr_table[0] == $cfg['Server']['table_coords']) {
  117.                 $cfgRelation['table_coords']    = $curr_table[0];
  118.             } else if ($curr_table[0] == $cfg['Server']['column_info']) {
  119.                 $cfgRelation['column_info'] = $curr_table[0];
  120.             } else if ($curr_table[0] == $cfg['Server']['pdf_pages']) {
  121.                 $cfgRelation['pdf_pages']       = $curr_table[0];
  122.             } else if ($curr_table[0] == $cfg['Server']['history']) {
  123.                 $cfgRelation['history'] = $curr_table[0];
  124.             }
  125.         } // end while
  126.     }
  127.  
  128.     if (isset($cfgRelation['relation'])) {
  129.         $cfgRelation['relwork']         = TRUE;
  130.         if (isset($cfgRelation['table_info'])) {
  131.                 $cfgRelation['displaywork'] = TRUE;
  132.         }
  133.     }
  134.     if (isset($cfgRelation['table_coords']) && isset($cfgRelation['pdf_pages'])) {
  135.         $cfgRelation['pdfwork']     = TRUE;
  136.     }
  137.     if (isset($cfgRelation['column_info'])) {
  138.         $cfgRelation['commwork']    = TRUE;
  139.  
  140.         if ($cfg['Server']['verbose_check']) {
  141.             $mime_query  = 'SHOW FIELDS FROM ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['column_info']);
  142.             $mime_rs     = PMA_query_as_cu($mime_query, FALSE);
  143.  
  144.             $mime_field_mimetype                = FALSE;
  145.             $mime_field_transformation          = FALSE;
  146.             $mime_field_transformation_options  = FALSE;
  147.             while ($curr_mime_field = @PMA_DBI_fetch_row($mime_rs)) {
  148.                 if ($curr_mime_field[0] == 'mimetype') {
  149.                     $mime_field_mimetype               = TRUE;
  150.                 } else if ($curr_mime_field[0] == 'transformation') {
  151.                     $mime_field_transformation         = TRUE;
  152.                 } else if ($curr_mime_field[0] == 'transformation_options') {
  153.                     $mime_field_transformation_options = TRUE;
  154.                 }
  155.             }
  156.             PMA_DBI_free_result($mime_rs);
  157.  
  158.             if ($mime_field_mimetype == TRUE
  159.                 && $mime_field_transformation == TRUE
  160.                 && $mime_field_transformation_options == TRUE) {
  161.                 $cfgRelation['mimework'] = TRUE;
  162.             }
  163.         } else {
  164.             $cfgRelation['mimework'] = TRUE;
  165.         }
  166.     }
  167.  
  168.     if (isset($cfgRelation['history'])) {
  169.         $cfgRelation['historywork']     = TRUE;
  170.     }
  171.  
  172.     if (isset($cfgRelation['bookmark'])) {
  173.         $cfgRelation['bookmarkwork']     = TRUE;
  174.     }
  175.  
  176.     if ($cfgRelation['relwork'] == TRUE && $cfgRelation['displaywork'] == TRUE
  177.         && $cfgRelation['pdfwork'] == TRUE && $cfgRelation['commwork'] == TRUE
  178.         && $cfgRelation['mimework'] == TRUE && $cfgRelation['historywork'] == TRUE
  179.         && $cfgRelation['bookmarkwork'] == TRUE) {
  180.         $cfgRelation['allworks'] = TRUE;
  181.     }
  182.     if ($tab_rs) {
  183.         PMA_DBI_free_result($tab_rs);
  184.     } else {
  185.         $cfg['Server']['pmadb'] = FALSE;
  186.     }
  187.  
  188.     if ($verbose == TRUE) {
  189.         $shit     = '<font color="red"><b>' . $GLOBALS['strNotOK'] . '</b></font> [ <a href="Documentation.html#%s">' . $GLOBALS['strDocu'] . '</a> ]';
  190.         $hit      = '<font color="green"><b>' . $GLOBALS['strOK'] . '</b></font>';
  191.         $enabled  = '<font color="green">' . $GLOBALS['strEnabled'] . '</font>';
  192.         $disabled = '<font color="red">'   . $GLOBALS['strDisabled'] . '</font>';
  193.  
  194.         echo '<table>' . "\n";
  195.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'pmadb\'] ... </th><td align="right">'
  196.              . (($cfg['Server']['pmadb'] == FALSE) ? sprintf($shit, 'pmadb') : $hit)
  197.              . '</td></tr>' . "\n";
  198.         echo '    <tr><td> </td></tr>' . "\n";
  199.  
  200.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'relation\'] ... </th><td align="right">'
  201.              . ((isset($cfgRelation['relation'])) ? $hit : sprintf($shit, 'relation'))
  202.              . '</td></tr>' . "\n";
  203.         echo '    <tr><td colspan=2 align="center">'. $GLOBALS['strGeneralRelationFeat'] . ': '
  204.              . (($cfgRelation['relwork'] == TRUE) ? $enabled :  $disabled)
  205.              . '</td></tr>' . "\n";
  206.         echo '    <tr><td> </td></tr>' . "\n";
  207.  
  208.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'table_info\']   ... </th><td align="right">'
  209.              . (($cfgRelation['displaywork'] == FALSE) ? sprintf($shit, 'table_info') : $hit)
  210.              . '</td></tr>' . "\n";
  211.         echo '    <tr><td colspan=2 align="center">' . $GLOBALS['strDisplayFeat'] . ': '
  212.              . (($cfgRelation['displaywork'] == TRUE) ? $enabled : $disabled)
  213.              . '</td></tr>' . "\n";
  214.         echo '    <tr><td> </td></tr>' . "\n";
  215.  
  216.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'table_coords\'] ... </th><td align="right">'
  217.              . ((isset($cfgRelation['table_coords'])) ? $hit : sprintf($shit, 'table_coords'))
  218.              . '</td></tr>' . "\n";
  219.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'pdf_pages\'] ... </th><td align="right">'
  220.              . ((isset($cfgRelation['pdf_pages'])) ? $hit : sprintf($shit, 'table_coords'))
  221.              . '</td></tr>' . "\n";
  222.         echo '    <tr><td colspan=2 align="center">' . $GLOBALS['strCreatePdfFeat'] . ': '
  223.              . (($cfgRelation['pdfwork'] == TRUE) ? $enabled : $disabled)
  224.              . '</td></tr>' . "\n";
  225.         echo '    <tr><td> </td></tr>' . "\n";
  226.  
  227.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'column_info\'] ... </th><td align="right">'
  228.              . ((isset($cfgRelation['column_info'])) ? $hit : sprintf($shit, 'col_com'))
  229.              . '</td></tr>' . "\n";
  230.         echo '    <tr><td colspan=2 align="center">' . $GLOBALS['strColComFeat'] . ': '
  231.              . (($cfgRelation['commwork'] == TRUE) ? $enabled : $disabled)
  232.              . '</td></tr>' . "\n";
  233.         echo '    <tr><td colspan=2 align="center">' . $GLOBALS['strBookmarkQuery'] . ': '
  234.              . (($cfgRelation['bookmarkwork'] == TRUE) ? $enabled : $disabled)
  235.              . '</td></tr>' . "\n";
  236.         echo '    <tr><th align="left">MIME ...</th><td align="right">'
  237.              . (($cfgRelation['mimework'] == TRUE) ? $hit : sprintf($shit, 'col_com'))
  238.              . '</td></tr>' . "\n";
  239.  
  240.              if (($cfgRelation['commwork'] == TRUE) && ($cfgRelation['mimework'] != TRUE)) {
  241.                  echo '<tr><td colspan=2 align="left">' . $GLOBALS['strUpdComTab'] . '</td></tr>' . "\n";
  242.              }
  243.  
  244.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'history\'] ... </th><td align="right">'
  245.              . ((isset($cfgRelation['history'])) ? $hit : sprintf($shit, 'history'))
  246.              . '</td></tr>' . "\n";
  247.         echo '    <tr><td colspan=2 align="center">' . $GLOBALS['strQuerySQLHistory'] . ': '
  248.              . (($cfgRelation['historywork'] == TRUE) ? $enabled : $disabled)
  249.              . '</td></tr>' . "\n";
  250.  
  251.         echo '</table>' . "\n";
  252.     } // end if ($verbose == TRUE) {
  253.  
  254.     return $cfgRelation;
  255. } // end of the 'PMA_getRelationsParam()' function
  256.  
  257.  
  258. /**
  259.  * Gets all Relations to foreign tables for a given table or
  260.  * optionally a given column in a table
  261.  *
  262.  * @param   string   the name of the db to check for
  263.  * @param   string   the name of the table to check for
  264.  * @param   string   the name of the column to check for
  265.  * @param   string   the source for foreign key information
  266.  *
  267.  * @return  array    db,table,column
  268.  *
  269.  * @global  array    the list of relations settings
  270.  * @global  string   the URL of the page to show in case of error
  271.  *
  272.  * @access  public
  273.  *
  274.  * @author  Mike Beck <mikebeck@users.sourceforge.net> and Marc Delisle
  275.  */
  276. function PMA_getForeigners($db, $table, $column = '', $source = 'both') {
  277.     global $cfgRelation, $err_url_0;
  278.  
  279.     if ($cfgRelation['relwork'] && ($source == 'both' || $source == 'internal')) {
  280.         $rel_query          = 'SELECT master_field, foreign_db, foreign_table, foreign_field'
  281.                             . ' FROM ' . PMA_backquote($cfgRelation['relation'])
  282.                             . ' WHERE master_db =  \'' . PMA_sqlAddslashes($db) . '\' '
  283.                             . ' AND   master_table = \'' . PMA_sqlAddslashes($table) . '\' ';
  284.         if (!empty($column)) {
  285.             $rel_query .= ' AND   master_field = \'' . PMA_sqlAddslashes($column) . '\'';
  286.         }
  287.         $relations     = PMA_query_as_cu($rel_query);
  288.         $i = 0;
  289.         while ($relrow = PMA_DBI_fetch_assoc($relations)) {
  290.             $field                            = $relrow['master_field'];
  291.             $foreign[$field]['foreign_db']    = $relrow['foreign_db'];
  292.             $foreign[$field]['foreign_table'] = $relrow['foreign_table'];
  293.             $foreign[$field]['foreign_field'] = $relrow['foreign_field'];
  294.             $i++;
  295.         } // end while
  296.         PMA_DBI_free_result($relations);
  297.         unset($relations);
  298.     }
  299.  
  300.     if (($source == 'both' || $source == 'innodb') && !empty($table)) {
  301.         $show_create_table_query = 'SHOW CREATE TABLE '
  302.             . PMA_backquote($db) . '.' . PMA_backquote($table);
  303.         $show_create_table_res = PMA_DBI_query($show_create_table_query);
  304.         list(,$show_create_table) = PMA_DBI_fetch_row($show_create_table_res);
  305.         PMA_DBI_free_result($show_create_table_res);
  306.         unset($show_create_table_res, $show_create_table_query);
  307.         $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
  308.  
  309.         foreach ($analyzed_sql[0]['foreign_keys'] AS $one_key) {
  310.  
  311.         // the analyzer may return more than one column name in the
  312.         // index list or the ref_index_list
  313.             foreach ($one_key['index_list'] AS $i => $field) {
  314.  
  315.         // If a foreign key is defined in the 'internal' source (pmadb)
  316.         // and in 'innodb', we won't get it twice if $source='both'
  317.         // because we use $field as key
  318.  
  319.                 // The parser looks for a CONSTRAINT clause just before
  320.                 // the FOREIGN KEY clause. It finds it (as output from
  321.                 // SHOW CREATE TABLE) in MySQL 4.0.13, but not in older
  322.                 // versions like 3.23.58. 
  323.                 // In those cases, the FOREIGN KEY parsing will put numbers
  324.                 // like -1, 0, 1... instead of the constraint number.
  325.  
  326.                 if (isset($one_key['constraint'])) {
  327.                     $foreign[$field]['constraint'] = $one_key['constraint'];
  328.                 }
  329.  
  330.                 if (isset($one_key['ref_db_name'])) {
  331.                     $foreign[$field]['foreign_db']    = $one_key['ref_db_name'];
  332.                 } else {
  333.                     $foreign[$field]['foreign_db']    = $db;
  334.                 }
  335.                 $foreign[$field]['foreign_table'] = $one_key['ref_table_name'];
  336.                 $foreign[$field]['foreign_field'] = $one_key['ref_index_list'][$i];
  337.                 if (isset($one_key['on_delete'])) {
  338.                     $foreign[$field]['on_delete'] = $one_key['on_delete'];
  339.                 }
  340.                 if (isset($one_key['on_update'])) {
  341.                     $foreign[$field]['on_update'] = $one_key['on_update'];
  342.                 }
  343.             }
  344.         }
  345.     }
  346.  
  347.     /**
  348.      * Emulating relations for some information_schema tables
  349.      */
  350.     if (PMA_MYSQL_INT_VERSION >= 50002 && $db == 'information_schema'
  351.         && ($source == 'internal' || $source == 'both')) {
  352.  
  353.         require_once('./libraries/information_schema_relations.lib.php');
  354.  
  355.         if (!isset($foreign)) {
  356.             $foreign = array();
  357.         }
  358.  
  359.         if (isset($GLOBALS['information_schema_relations'][$table])) {
  360.             foreach ($GLOBALS['information_schema_relations'][$table] as $field => $relations) {
  361.                 if ((empty($column) || $column == $field) && empty($foreign[$field])) {
  362.                     $foreign[$field] = $relations;
  363.                 }
  364.             }
  365.         }
  366.     }
  367.  
  368.     if (!empty($foreign) && is_array($foreign)) {
  369.        return $foreign;
  370.     } else {
  371.         return FALSE;
  372.     }
  373.  
  374. } // end of the 'PMA_getForeigners()' function
  375.  
  376.  
  377. /**
  378.  * Gets the display field of a table
  379.  *
  380.  * @param   string   the name of the db to check for
  381.  * @param   string   the name of the table to check for
  382.  *
  383.  * @return  string   field name
  384.  *
  385.  * @global  array    the list of relations settings
  386.  *
  387.  * @access  public
  388.  *
  389.  * @author  Mike Beck <mikebeck@users.sourceforge.net>
  390.  */
  391. function PMA_getDisplayField($db, $table) {
  392.     global $cfgRelation;
  393.  
  394.     /**
  395.      * Try to fetch the display field from DB.
  396.      */
  397.     if (trim(@$cfgRelation['table_info']) != '') {
  398.  
  399.         $disp_query = 'SELECT display_field FROM ' . PMA_backquote($cfgRelation['table_info'])
  400.                     . ' WHERE db_name    = \'' . PMA_sqlAddslashes($db) . '\''
  401.                     . ' AND   table_name = \'' . PMA_sqlAddslashes($table) . '\'';
  402.  
  403.         $disp_res   = PMA_query_as_cu($disp_query);
  404.         $row        = ($disp_res ? PMA_DBI_fetch_assoc($disp_res) : '');
  405.         PMA_DBI_free_result($disp_res);
  406.         if (isset($row['display_field'])) {
  407.             return $row['display_field'];
  408.         }
  409.  
  410.     }
  411.  
  412.     /**
  413.      * Emulating the display field for some information_schema tables.
  414.      */
  415.     if (PMA_MYSQL_INT_VERSION >= 50002 && $db == 'information_schema') {
  416.         switch ($table) {
  417.             case 'CHARACTER_SETS': return 'DESCRIPTION';
  418.             case 'TABLES':         return 'TABLE_COMMENT';
  419.         }
  420.     }
  421.  
  422.     /**
  423.      * No Luck...
  424.      */
  425.     return FALSE;
  426.  
  427. } // end of the 'PMA_getDisplayField()' function
  428.  
  429.  
  430. /**
  431.  * Gets the comments for all rows of a table
  432.  *
  433.  * @param   string   the name of the db to check for
  434.  * @param   string   the name of the table to check for
  435.  *
  436.  * @return  array    [field_name] = comment
  437.  *
  438.  * @global  array    the list of relations settings
  439.  *
  440.  * @access  public
  441.  *
  442.  * @authors  Mike Beck <mikebeck@users.sourceforge.net>
  443.  *           and lem9
  444.  */
  445. function PMA_getComments($db, $table = '') {
  446.     global $cfgRelation;
  447.  
  448.     if ($table != '') {
  449.  
  450.         // MySQL 4.1.x native column comments
  451.         if (PMA_MYSQL_INT_VERSION >= 40100) {
  452.             $fields = PMA_DBI_get_fields($db, $table);
  453.             if ($fields) {
  454.                 foreach($fields as $key=>$field) {
  455.                     $tmp_col = $field['Field'];
  456.                     if (!empty($field['Comment'])) {
  457.                         $native_comment[$tmp_col] = $field['Comment'];
  458.                     }
  459.                 }
  460.             }
  461.         }
  462.  
  463.         // pmadb internal column comments
  464.         // (this function can be called even if $cfgRelation['commwork'] is
  465.         // FALSE, to get native column comments, so recheck here)
  466.         if ($cfgRelation['commwork']) {
  467.             $com_qry = 'SELECT column_name, comment FROM ' . PMA_backquote($cfgRelation['db']) . '.' .PMA_backquote($cfgRelation['column_info'])
  468.                      . ' WHERE db_name    = \'' . PMA_sqlAddslashes($db) . '\''
  469.                      . ' AND   table_name = \'' . PMA_sqlAddslashes($table) . '\'';
  470.             $com_rs   = PMA_query_as_cu($com_qry, TRUE, PMA_DBI_QUERY_STORE);
  471.         }
  472.     } else {
  473.         // pmadb internal db comments
  474.         $com_qry = 'SELECT ' . PMA_backquote('comment') . ' FROM ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['column_info'])
  475.                  . ' WHERE db_name     = \'' . PMA_sqlAddslashes($db) . '\''
  476.                  . ' AND   table_name  = \'\''
  477.                  . ' AND   column_name = \'(db_comment)\'';
  478.         $com_rs   = PMA_query_as_cu($com_qry, TRUE, PMA_DBI_QUERY_STORE);
  479.     }
  480.  
  481.  
  482.     if (isset($com_rs) && PMA_DBI_num_rows($com_rs) > 0) {
  483.         $i = 0;
  484.         while ($row = PMA_DBI_fetch_assoc($com_rs)) {
  485.             $i++;
  486.             $col           = ($table != '' ? $row['column_name'] : $i);
  487.  
  488.             if (strlen($row['comment']) > 0) {
  489.                 $comment[$col] = $row['comment'];
  490.                 // if this version supports native comments and this function
  491.                 // was called with a table parameter 
  492.                 if (PMA_MYSQL_INT_VERSION >= 40100 && !empty($table)) {
  493.                     // if native comment found, use it instead of pmadb
  494.                     if (!empty($native_comment[$col])) {
  495.                         $comment[$col] = $native_comment[$col];
  496.                     } else {
  497.                         // no native comment, so migrate pmadb-style to native
  498.                         PMA_setComment($db, $table, $col, $comment[$col],'','native');
  499.                         // and erase the pmadb-style comment
  500.                         PMA_setComment($db, $table, $col, '','','pmadb');
  501.                     }
  502.                 }
  503.             }
  504.         } // end while
  505.  
  506.         PMA_DBI_free_result($com_rs);
  507.         unset($com_rs);
  508.     } else {
  509.         if (isset($native_comment)) {
  510.             $comment = $native_comment;
  511.         }
  512.     }
  513.  
  514.     if (isset($comment) && is_array($comment)) {
  515.         return $comment;
  516.      } else {
  517.         return FALSE;
  518.      }
  519.  } // end of the 'PMA_getComments()' function
  520.  
  521. /**
  522.  * Adds/removes slashes if required
  523.  *
  524.  * @param   string  the string to slash
  525.  *
  526.  * @return  string  the slashed string
  527.  *
  528.  * @access  public
  529.  */
  530. function PMA_handleSlashes($val) {
  531.   return (get_magic_quotes_gpc() ? str_replace('\\"', '"', $val) : PMA_sqlAddslashes($val));
  532. } // end of the "PMA_handleSlashes()" function
  533.  
  534. /**
  535.  * Set a single comment to a certain value.
  536.  *
  537.  * @param   string   the name of the db
  538.  * @param   string   the name of the table (may be empty in case of a db comment)
  539.  * @param   string   the name of the column
  540.  * @param   string   the value of the column
  541.  * @param   string   (optional) if a column is renamed, this is the name of the former key which will get deleted
  542.  * @param   string   whether we set pmadb comments, native comments or both
  543.  *
  544.  * @return  boolean  true, if comment-query was made.
  545.  *
  546.  * @global  array    the list of relations settings
  547.  *
  548.  * @access  public
  549.  */
  550. function PMA_setComment($db, $table, $col, $comment, $removekey = '', $mode='auto') {
  551.     global $cfgRelation;
  552.  
  553.     if ($mode=='auto') {
  554.         if (PMA_MYSQL_INT_VERSION >= 40100) {
  555.             $mode='native';
  556.         } else {
  557.             $mode='pmadb';
  558.         }
  559.     }
  560.  
  561.     // native mode is only for column comments so we need a table name
  562.     if ($mode == 'native' && !empty($table)) {
  563.         $fields = PMA_DBI_get_fields($db, $table);
  564.  
  565.  
  566.     // Get more complete field information
  567.     // For now, this is done just for MySQL 4.1.2+ new TIMESTAMP options
  568.     // but later, if the analyser returns more information, it
  569.     // could be executed for any MySQL version and replace
  570.     // the info given by SHOW FULL FIELDS FROM.
  571.     // TODO: put this code into a require()
  572.     // or maybe make it part of PMA_DBI_get_fields();
  573.  
  574.     if (PMA_MYSQL_INT_VERSION >= 40102) {
  575.         $show_create_table_query = 'SHOW CREATE TABLE '
  576.             . PMA_backquote($db) . '.' . PMA_backquote($table);
  577.         $show_create_table_res = PMA_DBI_query($show_create_table_query);
  578.         list(,$show_create_table) = PMA_DBI_fetch_row($show_create_table_res);
  579.         PMA_DBI_free_result($show_create_table_res);
  580.         unset($show_create_table_res, $show_create_table_query);
  581.         $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
  582.     }
  583.  
  584.         // TODO: get directly the information of $col
  585.         foreach($fields as $key=>$field) {
  586.             $tmp_col = $field['Field'];
  587.             $types[$tmp_col] = $field['Type'];
  588.             $collations[$tmp_col] = $field['Collation'];
  589.             $nulls[$tmp_col] = $field['Null'];
  590.             $defaults[$tmp_col] = $field['Default'];
  591.             $extras[$tmp_col] = $field['Extra'];
  592.  
  593.             if (PMA_MYSQL_INT_VERSION >= 40102 && isset($analyzed_sql[0]['create_table_fields'][$tmp_col]['on_update_current_timestamp'])) {
  594.                 $extras[$tmp_col] = 'ON UPDATE CURRENT_TIMESTAMP';
  595.             }
  596.  
  597.             if (PMA_MYSQL_INT_VERSION >= 40102 && isset($analyzed_sql[0]['create_table_fields'][$tmp_col]['default_current_timestamp'])) {
  598.                 $default_current_timestamps[$tmp_col] = TRUE; 
  599.             } else {
  600.                 $default_current_timestamps[$tmp_col] = FALSE; 
  601.             }
  602.  
  603.             if ($tmp_col == $col) {
  604.                 break;
  605.             }
  606.         }
  607.         if ($nulls[$col] == 'YES') {
  608.             $nulls[$col] = '';
  609.         } else {
  610.             $nulls[$col] = 'NOT NULL';
  611.         }
  612.  
  613.         $query = 'ALTER TABLE ' . PMA_backquote($table) . ' CHANGE '
  614.             . PMA_generateAlterTable($col, $col, $types[$col], $collations[$col], $nulls[$col], $defaults[$col], $default_current_timestamps[$col], $extras[$col], $comment);
  615.  
  616.         PMA_DBI_try_query($query, NULL, PMA_DBI_QUERY_STORE);
  617.         return TRUE;
  618.     }
  619.  
  620.     // $mode == 'pmadb' section: 
  621.     
  622.     $cols = array(
  623.         'db_name'     => 'db_name    ',
  624.         'table_name'  => 'table_name ',
  625.         'column_name' => 'column_name'
  626.     );
  627.  
  628.     if ($removekey != '' AND $removekey != $col) {
  629.         $remove_query = 'DELETE FROM ' . PMA_backquote($cfgRelation['column_info'])
  630.                       . ' WHERE ' . $cols['db_name']     . ' = \'' . PMA_sqlAddslashes($db) . '\''
  631.                       . ' AND   ' . $cols['table_name']  . ' = \'' . PMA_sqlAddslashes($table) . '\''
  632.                       . ' AND   ' . $cols['column_name'] . ' = \'' . PMA_sqlAddslashes($removekey) . '\'';
  633.         PMA_query_as_cu($remove_query);
  634.         unset($remove_query);
  635.     }
  636.  
  637.     $test_qry = 'SELECT ' . PMA_backquote('comment') . ', mimetype, transformation, transformation_options FROM ' . PMA_backquote($cfgRelation['column_info'])
  638.               . ' WHERE ' . $cols['db_name']     . ' = \'' . PMA_sqlAddslashes($db) . '\''
  639.               . ' AND   ' . $cols['table_name']  . ' = \'' . PMA_sqlAddslashes($table) . '\''
  640.               . ' AND   ' . $cols['column_name'] . ' = \'' . PMA_sqlAddslashes($col) . '\'';
  641.     $test_rs   = PMA_query_as_cu($test_qry, TRUE, PMA_DBI_QUERY_STORE);
  642.  
  643.     if ($test_rs && PMA_DBI_num_rows($test_rs) > 0) {
  644.         $row = PMA_DBI_fetch_assoc($test_rs);
  645.         PMA_DBI_free_result($test_rs);
  646.  
  647.         if (strlen($comment) > 0 || strlen($row['mimetype']) > 0 || strlen($row['transformation']) > 0 || strlen($row['transformation_options']) > 0) {
  648.             $upd_query = 'UPDATE ' . PMA_backquote($cfgRelation['column_info'])
  649.                        . ' SET ' . PMA_backquote('comment') . ' = \'' . PMA_sqlAddslashes($comment) . '\''
  650.                        . ' WHERE ' . $cols['db_name']     . ' = \'' . PMA_sqlAddslashes($db) . '\''
  651.                        . ' AND   ' . $cols['table_name']  . ' = \'' . PMA_sqlAddslashes($table) . '\''
  652.                        . ' AND   ' . $cols['column_name'] . ' = \'' . PMA_sqlAddSlashes($col) . '\'';
  653.         } else {
  654.             $upd_query = 'DELETE FROM ' . PMA_backquote($cfgRelation['column_info'])
  655.                        . ' WHERE ' . $cols['db_name']     . ' = \'' . PMA_sqlAddslashes($db) . '\''
  656.                        . ' AND   ' . $cols['table_name']  . ' = \'' . PMA_sqlAddslashes($table) . '\''
  657.                        . ' AND   ' . $cols['column_name'] . ' = \'' . PMA_sqlAddslashes($col) . '\'';
  658.         }
  659.     } else if (strlen($comment) > 0) {
  660.         $upd_query = 'INSERT INTO ' . PMA_backquote($cfgRelation['column_info'])
  661.                    . ' (db_name, table_name, column_name, ' . PMA_backquote('comment') . ') '
  662.                    . ' VALUES('
  663.                    . '\'' . PMA_sqlAddslashes($db) . '\','
  664.                    . '\'' . PMA_sqlAddslashes($table) . '\','
  665.                    . '\'' . PMA_sqlAddslashes($col) . '\','
  666.                    . '\'' . PMA_sqlAddslashes($comment) . '\')';
  667.     }
  668.  
  669.     if (isset($upd_query)){
  670.         $upd_rs    = PMA_query_as_cu($upd_query);
  671.         unset($upd_query);
  672.         return true;
  673.     } else {
  674.         return false;
  675.     }
  676. } // end of 'PMA_setComment()' function
  677.  
  678. /**
  679.  * Set a SQL history entry
  680.  *
  681.  * @param   string   the name of the db
  682.  * @param   string   the name of the table
  683.  * @param   string   the username
  684.  * @param   string   the sql query
  685.  *
  686.  * @global  array    the list of relations settings
  687.  *
  688.  * @return  boolean  true
  689.  *
  690.  * @access  public
  691.  */
  692. function PMA_setHistory($db, $table, $username, $sqlquery) {
  693.     global $cfgRelation;
  694.  
  695.     $hist_rs    = PMA_query_as_cu('INSERT INTO ' . PMA_backquote($cfgRelation['history']) . ' ('
  696.                 . PMA_backquote('username') . ','
  697.                 . PMA_backquote('db') . ','
  698.                 . PMA_backquote('table') . ','
  699.                 . PMA_backquote('timevalue') . ','
  700.                 . PMA_backquote('sqlquery')
  701.                 . ') VALUES ('
  702.                 . '\'' . PMA_sqlAddslashes($username) . '\','
  703.                 . '\'' . PMA_sqlAddslashes($db) . '\','
  704.                 . '\'' . PMA_sqlAddslashes($table) . '\','
  705.                 . 'NOW(),'
  706.                 . '\'' . PMA_sqlAddslashes($sqlquery) . '\')');
  707.     return true;
  708. } // end of 'PMA_setHistory()' function
  709.  
  710. /**
  711.  * Gets a SQL history entry
  712.  *
  713.  * @param   string   the username
  714.  *
  715.  * @global  array    the list of relations settings
  716.  *
  717.  * @return  array    list of history items
  718.  *
  719.  * @access  public
  720.  */
  721. function PMA_getHistory($username) {
  722.     global $cfgRelation;
  723.  
  724.     $hist_query = 'SELECT '
  725.                 . PMA_backquote('db') . ','
  726.                 . PMA_backquote('table') . ','
  727.                 . PMA_backquote('sqlquery')
  728.                 . ' FROM ' . PMA_backquote($cfgRelation['history'])
  729.                 . ' WHERE username = \'' . PMA_sqlAddslashes($username) . '\''
  730.                 . ' ORDER BY id DESC';
  731.  
  732.     $hist_rs = PMA_query_as_cu($hist_query);
  733.     unset($hist_query);
  734.  
  735.     $history = array();
  736.  
  737.     while ($row = PMA_DBI_fetch_assoc($hist_rs)) {
  738.         $history[] = $row;
  739.     }
  740.     PMA_DBI_free_result($hist_rs);
  741.  
  742.     return $history;
  743.  
  744. } // end of 'PMA_getHistory()' function
  745.  
  746. /**
  747.  * Set a SQL history entry
  748.  *
  749.  * @param   string   the name of the db
  750.  * @param   string   the name of the table
  751.  * @param   string   the username
  752.  * @param   string   the sql query
  753.  *
  754.  * @global  array    the list of relations settings
  755.  * @global  array    global phpMyAdmin configuration
  756.  *
  757.  * @return  boolean  true
  758.  *
  759.  * @access  public
  760.  */
  761. function PMA_purgeHistory($username) {
  762.     global $cfgRelation, $cfg;
  763.  
  764.     $purge_query = 'SELECT timevalue FROM ' . PMA_backquote($cfgRelation['history'])
  765.                  . ' WHERE username = \'' . PMA_sqlAddSlashes($username) . '\''
  766.                  . ' ORDER BY timevalue DESC LIMIT ' . $cfg['QueryHistoryMax'] . ', 1';
  767.     $purge_rs = PMA_query_as_cu($purge_query);
  768.     $i = 0;
  769.     $row = PMA_DBI_fetch_row($purge_rs);
  770.     PMA_DBI_free_result($purge_rs);
  771.  
  772.     if (is_array($row) && isset($row[0]) && $row[0] > 0) {
  773.         $maxtime = $row[0];
  774.         // quotes added around $maxtime to prevent a difficult to
  775.         // reproduce problem
  776.         $remove_rs = PMA_query_as_cu('DELETE FROM ' . PMA_backquote($cfgRelation['history']) . ' WHERE timevalue <= "' . $maxtime . '"');
  777.     }
  778.  
  779.     return true;
  780. } // end of 'PMA_purgeHistory()' function
  781.  
  782. /**
  783.  * Outputs dropdown with values of foreign fields
  784.  *
  785.  * @param   string   the query of the foreign keys
  786.  * @param   string   the foreign field
  787.  * @param   string   the foreign field to display
  788.  * @param   string   the current data of the dropdown
  789.  *
  790.  * @global  array    global phpMyAdmin configuration
  791.  *
  792.  * @return  string   the <option value=""><option>s
  793.  *
  794.  * @access  public
  795.  */
  796. function PMA_foreignDropdown($disp, $foreign_field, $foreign_display, $data, $max = 100) {
  797.     global $cfg;
  798.  
  799.     $ret = '<option value=""></option>' . "\n";
  800.  
  801.     $reloptions = array('content-id' => array(), 'id-content' => array());
  802.     
  803.     foreach ($disp AS $disp_key => $relrow) {
  804.         $key   = $relrow[$foreign_field];
  805.  
  806.         // if the display field has been defined for the foreign table
  807.         if ($foreign_display) {
  808.             if (PMA_strlen($relrow[$foreign_display]) <= $cfg['LimitChars']) {
  809.                 $value  = htmlspecialchars($relrow[$foreign_display]);
  810.                 $vtitle = '';
  811.             } else {
  812.                 $vtitle = htmlspecialchars($relrow[$foreign_display]);
  813.                 $value  = htmlspecialchars(substr($vtitle, 0, $cfg['LimitChars']) . '...');
  814.             }
  815.         } else {
  816.             $vtitle = $value = '';
  817.         } // end if ($foreign_display)
  818.  
  819.         $reloption = '<option value="' . htmlspecialchars($key) . '"';
  820.         if ($vtitle != '') {
  821.             $reloption .= ' title="' . $vtitle . '"';
  822.         }
  823.  
  824.         if ($key == $data) {
  825.            $reloption .= ' selected="selected"';
  826.         } // end if
  827.  
  828.         $reloptions['id-content'][] = $reloption . '>' . $value . ' - ' . htmlspecialchars($key) .  '</option>' . "\n";
  829.         $reloptions['content-id'][] = $reloption . '>' . htmlspecialchars($key) .  ' - ' . $value . '</option>' . "\n";
  830.     } // end while
  831.  
  832.     // the list of keys looks better if not sorted by description
  833.     if ($cfg['NaturalOrder']) {
  834.         natsort($reloptions['content-id']); }
  835.     else {
  836.         asort($reloptions['content-id']);
  837.     }
  838.  
  839.     if ($max == -1 || count($reloptions['content-id']) < $max) {
  840.         $ret .= implode('', $reloptions['content-id']);
  841.         if (count($reloptions['content-id']) > 0) {
  842.             $ret .= '<option value=""></option>' . "\n";
  843.             $ret .= '<option value=""></option>' . "\n";
  844.         }
  845.     }
  846.  
  847.     $ret .= implode('', $reloptions['id-content']);
  848.  
  849.     return $ret;
  850. } // end of 'PMA_foreignDropdown()' function
  851.  
  852. ?>
  853.